﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;

namespace Tauren.Form.Infrastructure.RedisHelpe
{
    public interface IRedisClient
    {
        #region string 类型操作

        /// <summary>
        /// 设置字符串数据
        /// </summary>
        /// <param name="Key">缓存key</param>
        /// <param name="Content">内容</param>
        /// <returns></returns>
        bool SetStringValue(string Key, string Content);

        /// <summary>
        /// 保存单个key value
        /// </summary>
        /// <param name="key">Redis Key</param>
        /// <param name="value">保存的值</param>
        /// <param name="expiry">过期时间</param>
        /// <returns></returns>
        bool SetStringKey(string Key, string Content, TimeSpan? Expiry = default(TimeSpan?));

        /// <summary>
        ///  获取一个key的对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        T GetStringKey<T>(string Key) where T : class;

        /// <summary>
        /// 获取一个字符串对象
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        string GetStringValue(string Key);

        bool SetStringValue(string Key, object Content);

        /// <summary>
        /// 根据Key删除数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        bool DeleteStringKey(string Key);
        #endregion

        #region HASH类型封装
        /// <summary>
        /// 判断该字段是否存在 hash 中
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        bool HashExists(string redisKey, string hashField);

        /// <summary>
        /// 从 hash 中移除指定字段
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        bool HashDelete(string redisKey, string hashField);

        /// <summary>
        /// 从 hash 中移除指定字段（多个删除）
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        long HashDelete(string redisKey, IEnumerable<RedisValue> hashField);

        /// <summary>
        /// 在 hash 设定值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        bool HashSet(string redisKey, string hashField, string value);

        /// <summary>
        /// 在 hash 中设定值（多个）
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashFields"></param>
        void HashSet(string redisKey, IEnumerable<HashEntry> hashFields);

        /// <summary>
        /// 在 hash 中获取值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        RedisValue HashGet(string redisKey, string hashField);

        /// <summary>
        /// 在 hash 中获取值（多个）
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        RedisValue[] HashGet(string redisKey, RedisValue[] hashField);

        /// <summary>
        /// 从 hash 返回所有的字段值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        IEnumerable<RedisValue> HashKeys(string redisKey);

        /// <summary>
        /// 返回 hash 中的所有值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        RedisValue[] HashValues(string redisKey);

        /// <summary>
        /// 在 hash 设定值（序列化）
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        bool HashSet<T>(string redisKey, string hashField, T value);

        /// <summary>
        /// 在 hash 中获取值（反序列化）
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="hashField"></param>
        /// <returns></returns>
        T HashGet<T>(string redisKey, string hashField);
        #endregion

        #region List类型方法封装

        /// <summary>
         /// 移除并返回存储在该键列表的第一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        string ListLeftPop(string redisKey);


        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        string ListRightPop(string redisKey);

        /// <summary>
        /// 移除列表指定键上与该值相同的元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListRemove(string redisKey, string redisValue);

        /// <summary>
        /// 在列表尾部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListRightPush(string redisKey, string redisValue);

        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListLeftPush(string redisKey, string redisValue);

        /// <summary>
        /// 返回列表上该键的长度，如果不存在，返回 0
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        long ListLength(string redisKey);

        /// <summary>
        /// 返回在该列表上键所对应的元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        IEnumerable<RedisValue> ListRange(string redisKey);

        /// <summary>
        /// 返回在该列表上键所对应的元素
        /// </summary>
        /// <param name="redisKey">开始行</param>
        /// <param name="startRow">结束行</param>
        /// <returns></returns>
        IEnumerable<RedisValue> ListRange(string redisKey, int startRow, int endRow);

        /// <summary>
        /// 移除并返回存储在该键列表的第一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        T ListLeftPop<T>(string redisKey);

        /// <summary>
        /// 移除并返回存储在该键列表的最后一个元素
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        T ListRightPop<T>(string redisKey);
        /// <summary>
        /// 在列表尾部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListRightPush<T>(string redisKey, T redisValue);

        /// <summary>
        /// 在列表头部插入值。如果键不存在，先创建再插入值
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisValue"></param>
        /// <returns></returns>
        long ListLeftPush<T>(string redisKey, T redisValue);
        #endregion

        #region SortedSet类型方法封装
        /// <summary>
        /// SortedSet 新增
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="member"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        bool SortedSetAdd(string redisKey, string member, double score);

        /// <summary>
        /// 在有序集合中返回指定范围的元素，默认情况下从低到高。
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        IEnumerable<RedisValue> SortedSetRangeByRank(string redisKey);

        /// <summary>
        /// 返回有序集合的元素个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <returns></returns>
        long SortedSetLength(string redisKey);

        /// <summary>
        /// 返回有序集合的元素个数
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="memebr"></param>
        /// <returns></returns>
        bool SortedSetLength(string redisKey, string memebr);

        /// <summary>
        /// SortedSet 新增
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="member"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        bool SortedSetAdd<T>(string redisKey, T member, double score);
        #endregion
        /// <summary>
        /// 设置 Key 的时间
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="expiry"></param>
        /// <returns></returns>
        bool KeyExpire(string RedisKey, TimeSpan? Expiry);
        /// <summary>
        /// 重命名 Key
        /// </summary>
        /// <param name="redisKey"></param>
        /// <param name="redisNewKey"></param>
        /// <returns></returns>
        bool Rename(string redisKey, string redisNewKey);
    }
}
